//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability;
using EntLibContrib.Resource.Configuration;
using EntLibContrib.Resource.Configuration.Manageability;
using EntLibContrib.Resource.Configuration.Manageability.Tests.Adm;
using EntLibContrib.Resource.Configuration.Manageability.Tests.Mocks;

#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Resource.Configuration.Manageability.Tests
{
	[TestClass]
	public class BinaryResourceProviderDataManageabilityProviderFixture
	{
		private ConfigurationElementManageabilityProviderWrapper provider;
		private MockRegistryKey machineKey;
		private MockRegistryKey userKey;
		private IList<ConfigurationSetting> wmiSettings;
		private BinaryResourceProviderData configurationObject;

		[TestInitialize]
		public void SetUp()
		{
			provider = new ConfigurationElementManageabilityProviderWrapper(new BinaryResourceProviderDataManageabilityProvider());
			machineKey = new MockRegistryKey(true);
			userKey = new MockRegistryKey(true);
			wmiSettings = new List<ConfigurationSetting>();
			configurationObject = new BinaryResourceProviderData();
		}

		[TestMethod]
		public void ManageabilityProviderIsProperlyRegistered()
		{
			ConfigurationElementManageabilityProviderAttribute selectedAttribute = null;

			Assembly assembly = typeof(BinaryResourceProviderDataManageabilityProvider).Assembly;
			foreach (ConfigurationElementManageabilityProviderAttribute providerAttribute
				in assembly.GetCustomAttributes(typeof(ConfigurationElementManageabilityProviderAttribute), false))
			{
				if (providerAttribute.ManageabilityProviderType.Equals(typeof(BinaryResourceProviderDataManageabilityProvider)))
				{
					selectedAttribute = providerAttribute;
					break;
				}
			}

			Assert.IsNotNull(selectedAttribute);
			Assert.AreSame(typeof(ResourceManagerSettingsManageabilityProvider), selectedAttribute.SectionManageabilityProviderType);
			Assert.AreSame(typeof(BinaryResourceProviderData), selectedAttribute.TargetType);
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void ProviderThrowsWithConfigurationObjectOfWrongType()
		{
			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(new TestsConfigurationSection(), true, machineKey, userKey, true, wmiSettings);
		}

		[TestMethod]
		public void ConfigurationObjectIsNotModifiedIfThereAreNoPolicyOverrides()
		{
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, true, null, null, true, wmiSettings);

			Assert.AreEqual("path", configurationObject.ResourcePathName);
			Assert.AreEqual("base", configurationObject.ResourceBaseName);
		}

		[TestMethod]
		public void ConfigurationObjectIsModifiedIfThereAreMachinePolicyOverrides()
		{
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			machineKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourcePathNamePropertyName, "machine path");
			machineKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourceBaseNamePropertyName, "machine base");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, true, machineKey, null, true, wmiSettings);

			Assert.AreEqual("machine path", configurationObject.ResourcePathName);
			Assert.AreEqual("machine base", configurationObject.ResourceBaseName);
		}

		[TestMethod]
		public void ConfigurationObjectIsModifiedIfThereAreUserPolicyOverrides()
		{
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			userKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourcePathNamePropertyName, "user path");
			userKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourceBaseNamePropertyName, "user base");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, true, null, userKey, true, wmiSettings);

			Assert.AreEqual("user path", configurationObject.ResourcePathName);
			Assert.AreEqual("user base", configurationObject.ResourceBaseName);
		}

		[TestMethod]
		public void ConfigurationObjectIsNotModifiedIfThereArePolicyOverridesButGroupPoliciesAreDisabled()
		{
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			machineKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourcePathNamePropertyName, "machine path");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, false, machineKey, null, true, wmiSettings);

			Assert.AreEqual("path", configurationObject.ResourcePathName);
			Assert.AreEqual("base", configurationObject.ResourceBaseName);
		}

		[TestMethod]
		public void WmiSettingsAreNotGeneratedIfWmiIsDisabled()
		{
			configurationObject.Name = "provider name";
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, false, null, null, false, wmiSettings);

			Assert.AreEqual(0, wmiSettings.Count);
		}

		[TestMethod]
		public void WmiSettingsAreGeneratedIfWmiIsEnabled()
		{
			configurationObject.Name = "provider name";
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, false, null, null, true, wmiSettings);

			Assert.AreEqual(1, wmiSettings.Count);
			Assert.AreSame(typeof(BinaryResourceProviderSetting), wmiSettings[0].GetType());
			Assert.AreEqual("provider name", ((BinaryResourceProviderSetting)wmiSettings[0]).Name);
			Assert.AreEqual("path", ((BinaryResourceProviderSetting)wmiSettings[0]).ResourcePathName);
			Assert.AreEqual("base", ((BinaryResourceProviderSetting)wmiSettings[0]).ResourceBaseName);
		}

		[TestMethod]
		public void WmiSettingsAreGeneratedWithPolicyOverridesIfWmiIsEnabled()
		{
			configurationObject.Name = "provider name";
			configurationObject.ResourcePathName = "path";
			configurationObject.ResourceBaseName = "base";

			machineKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourcePathNamePropertyName, "machine path");
			machineKey.AddStringValue(BinaryResourceProviderDataManageabilityProvider.ResourceBaseNamePropertyName, "machine base");

			provider.InvokeOverrideWithGroupPoliciesAndGenerateWmiObjects(configurationObject, true, machineKey, null, true, wmiSettings);

			Assert.AreEqual(1, wmiSettings.Count);
			Assert.AreSame(typeof(BinaryResourceProviderSetting), wmiSettings[0].GetType());
			Assert.AreEqual("provider name", ((BinaryResourceProviderSetting)wmiSettings[0]).Name);
			Assert.AreEqual("machine path", ((BinaryResourceProviderSetting)wmiSettings[0]).ResourcePathName);
			Assert.AreEqual("machine base", ((BinaryResourceProviderSetting)wmiSettings[0]).ResourceBaseName);
		}

		//**** Note:Microsoft AdmContentBuilder clashes with EntLibContrib one so this test cannot be reproduced
		//[TestMethod]
		//public void ManageabilityProviderGeneratesProperAdmContent()
		//{
		//  DictionaryConfigurationSource configurationSource = new DictionaryConfigurationSource();

		//  MockAdmContentBuilder contentBuilder = new MockAdmContentBuilder();

		//  configurationObject.Type = typeof(Object);

		//  contentBuilder.StartCategory("category");
		//  contentBuilder.StartPolicy("policy", "policy key");
		//  provider.InvokeAddAdministrativeTemplateDirectives(contentBuilder, configurationObject, configurationSource, "TestApp");
		//  contentBuilder.EndPolicy();
		//  contentBuilder.EndCategory();

		//  MockAdmContent content = contentBuilder.GetMockContent();
		//  IEnumerator<AdmCategory> categoriesEnumerator = content.Categories.GetEnumerator();
		//  categoriesEnumerator.MoveNext();
		//  IEnumerator<AdmPolicy> policiesEnumerator = categoriesEnumerator.Current.Policies.GetEnumerator();
		//  policiesEnumerator.MoveNext();
		//  IEnumerator<AdmPart> partsEnumerator = policiesEnumerator.Current.Parts.GetEnumerator();
		//  Assert.IsTrue(partsEnumerator.MoveNext());
		//  Assert.AreSame(typeof(AdmEditTextPart), partsEnumerator.Current.GetType());
		//  Assert.IsNotNull(((AdmEditTextPart)partsEnumerator.Current).KeyName);
		//  Assert.AreEqual(BinaryResourceProviderDataManageabilityProvider.ResourcePathNamePropertyName, ((AdmEditTextPart)partsEnumerator.Current).ValueName);
		//  Assert.IsTrue(partsEnumerator.MoveNext());
		//  Assert.AreSame(typeof(AdmEditTextPart), partsEnumerator.Current.GetType());
		//  Assert.IsNotNull(((AdmEditTextPart)partsEnumerator.Current).KeyName);
		//  Assert.AreEqual(BinaryResourceProviderDataManageabilityProvider.ResourceBaseNamePropertyName, ((AdmEditTextPart)partsEnumerator.Current).ValueName);
		//  Assert.IsFalse(partsEnumerator.MoveNext());
		//}
	}
}